package com.hspedu.hspliving.commodity.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hspedu.hspliving.commodity.entity.CategoryEntity;
import com.hspedu.hspliving.commodity.service.CategoryService;
import com.hspedu.hspliving.commodity.vo.Catalog2Vo;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hspedu.common.utils.PageUtils;
import com.hspedu.common.utils.Query;
import com.hspedu.hspliving.commodity.dao.CategoryDao;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service("categoryService")
public class CategoryServiceImpl extends ServiceImpl<CategoryDao, CategoryEntity> implements CategoryService {

    /**
     * 这里我们会使用到java8的 流式计算(stream api) + 递归操作(有一定难度)
     *
     * @description: 返回所有分类及其子分类(层级关系 - 即树形)
     * @author: xujiabing
     * @date: 2024/5/15 20:36
     * @param:
     * @return: java.util.List<com.hspedu.common.commodity.entity.CategoryEntity>
     */
    @Override
    public List<CategoryEntity> listTree() {
        //1.先查出所有分类数据
        LambdaQueryWrapper<CategoryEntity> wrapper = new LambdaQueryWrapper<>();
        List<CategoryEntity> entityList = baseMapper.selectList(wrapper);
        //2.组装成层级树形结构[使用到 java8的 stream api + 递归操作]
        //2.1 过滤，返回1级分类
        //2.2 进行map映射操作，给每个分类设置对应的子分类
        //2.3 进行排序sorted操作
        //2.4 处理好的数据->集合返回
        List<CategoryEntity> categoryTree = entityList.stream().filter(categoryEntity -> {
            return categoryEntity.getParentId() == 0;
        }).map(categoryEntity -> {
            categoryEntity.setChildrenCategories(getChildrenCategories(entityList, categoryEntity));
            return categoryEntity;
        }).sorted((category1, category2) -> {
            //按照sort排序-升序
            return (category1.getSort() == null ? 0 : category1.getSort()) -
                    (category2.getSort() == null ? 0 : category2.getSort());
        }).collect(Collectors.toList());

        return categoryTree;
    }

    /**
     * 返回传入的1级菜单下的所有2级，3级...菜单
     *
     * @param entityList
     * @param local
     * @return
     */
    private List<CategoryEntity> getChildrenCategories(List<CategoryEntity> entityList, CategoryEntity local) {
        List<CategoryEntity> child = entityList.stream().filter(categoryEntity -> {
            return local.getId().equals(categoryEntity.getParentId());
            //也可以转成基本数据类型判断值
            //return local.getId().longValue() == categoryEntity.getParentId().longValue();
        }).map(categoryEntity -> {
            //将二级菜单作为根节点传入，进行递归操作
            categoryEntity.setChildrenCategories(getChildrenCategories(entityList, categoryEntity));
            return categoryEntity;
        }).sorted((category1, category2) -> {
            //按照sort排序-升序
            return (category1.getSort() == null ? 0 : category1.getSort()) -
                    (category2.getSort() == null ? 0 : category2.getSort());
        }).collect(Collectors.toList());

        return child;
    }

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<CategoryEntity> page = this.page(
                new Query<CategoryEntity>().getPage(params),
                new QueryWrapper<CategoryEntity>()
        );

        return new PageUtils(page);
    }

    /**
     * 通过 categoryId 属性组id返回分类id，指定格式
     * 返回cascadedCategoryId(是一个数组)的[第1 级分类id, 第2 级分类id, 第3 级分类id]
     *
     * @param categoryId
     * @return
     */
    @Override
    public Long[] getCascadedCategoryId(Long categoryId) {
        List<Long> cascadedCategoryId = new ArrayList<>();
        List<Long> list = getParentCategoryId(categoryId, cascadedCategoryId);
        //翻转list
        Collections.reverse(list);
        //转成数组
        Long[] array = list.toArray(new Long[list.size()]);
        return array;
    }

    /**
     * 该方法递归的找到categoryId 的所有父分类id , 并存放到categories
     *
     * @param categoryId
     * @param cascadedCategoryId
     * @return
     */
    List<Long> getParentCategoryId(Long categoryId, List<Long> cascadedCategoryId) {
        //1.添加到集合
        cascadedCategoryId.add(categoryId);
        //2.根据传入categoryId获取对应数据
        CategoryEntity categoryEntity = this.getById(categoryId);
        //3.判断+递归[301,21,1]
        if (!categoryEntity.getParentId().equals(0L)) {//说明还有上级分类
            getParentCategoryId(categoryEntity.getParentId(), cascadedCategoryId);
        }
        return cascadedCategoryId;
    }

    /**
     * 返回一级分类集合
     *
     * @return
     */
    @Override
    public List<CategoryEntity> getLevel1Categorys() {
        return baseMapper.selectList(new LambdaQueryWrapper<CategoryEntity>()
                .eq(CategoryEntity::getParentId, 0L));
    }

    /**
     * 返回指定格式 - 2级分类[包括3级分类]
     *
     * @return
     */
    @Override
    public Map<String, List<Catalog2Vo>> getCatalogJson() {
        //1.先得到所有分类数据,再进行处理
        List<CategoryEntity> categoryEntities = this.baseMapper.selectList(
                new LambdaQueryWrapper<CategoryEntity>()
                        .eq(CategoryEntity::getIsShow, 1));

        //2.查出所有一级分类
        List<CategoryEntity> level1Catalogs = getParent_cid(categoryEntities, 0L);
        //3.遍历1级分类
        Map<String, List<Catalog2Vo>> catalogMap = level1Catalogs
                .stream()
                .collect(Collectors.toMap(k -> {
                    return k.getId().toString();
                }, v -> {
                    //得到当前 一级分类对应二级分类
                    List<CategoryEntity> currLevel2Catalogs = getParent_cid(categoryEntities, v.getId());
                    //遍历2级分类
                    List<Catalog2Vo> catalog2Vos = null;

                    if (!currLevel2Catalogs.isEmpty()) {
                        catalog2Vos = currLevel2Catalogs.stream().map(l2 -> {
                            //构建 Catalog2Vo 对象
                            Catalog2Vo catalog2Vo = new Catalog2Vo();
                            catalog2Vo.setCatalog1Id(v.getId().toString());
                            catalog2Vo.setId(l2.getId().toString());
                            catalog2Vo.setName(l2.getName());

                            //遍历当前2级分类 下的 3级分类
                            List<CategoryEntity> currLevel3Catalogs = getParent_cid(categoryEntities, l2.getId());

                            List<Catalog2Vo.Category3Vo> catalog3List = null;

                            if (!currLevel3Catalogs.isEmpty()) {
                                //遍历返回的3级分类集合
                                catalog3List = currLevel3Catalogs.stream().map(l3 -> {
                                    //构建 3级分类 vo对象
                                    Catalog2Vo.Category3Vo category3Vo = new Catalog2Vo.Category3Vo();
                                    category3Vo.setCatalog2Id(l2.getId().toString());
                                    category3Vo.setId(l3.getId().toString());
                                    category3Vo.setName(l3.getName());
                                    return category3Vo;
                                }).collect(Collectors.toList());
                            }
                            catalog2Vo.setCatalog3List(catalog3List);

                            return catalog2Vo;
                        }).collect(Collectors.toList());

                    }

                    return catalog2Vos;
                }));

        return catalogMap;
    }

    /**
     * 通过分类的parent_id获取 子分类集合
     *
     * @param selectList 所有的分类数据
     * @param parentCid  指定的parent_id
     * @return
     */
    private List<CategoryEntity> getParent_cid(List<CategoryEntity> selectList
            , Long parentCid) {
        //通过parentCid 从selectList筛选 出指定的子分类集合
        return selectList.stream().filter(categoryEntity -> {
            return categoryEntity.getParentId().equals(parentCid);
        }).collect(Collectors.toList());
    }


}
